package com.iphanta.community.remote.service.impl;

import com.baidu.fsg.uid.UidGenerator;
import com.iphanta.community.common.BusinessException;
import com.iphanta.community.common.UserUtils;
import com.iphanta.community.common.utils.RedisKey;
import com.iphanta.community.common.utils.RedisKeyUtils;
import com.iphanta.community.common.utils.ResultUtils;
import com.iphanta.community.remote.common.RemoteResult;
import com.iphanta.community.remote.feign.UserCenterFeign;
import com.iphanta.community.remote.feign.VerifyTokenFeign;
import com.iphanta.community.remote.service.TimService;
import com.iphanta.community.remote.service.VerifyTokenService;
import com.iphanta.community.remote.traffic.GetPlayerInfoRequest;
import com.iphanta.community.remote.traffic.GetPlayerInfoResponse;
import com.iphanta.community.remote.traffic.VerifyTokenRequest;
import com.iphanta.community.remote.traffic.VerifyTokenResponse;
import com.iphanta.community.user.entity.Relation;
import com.iphanta.community.user.entity.UserBasicInfo;
import com.iphanta.community.user.mapper.RelationMapper;
import com.iphanta.community.user.mapper.UserBasicInfoMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author 墨声 E-mail: zehong.hongframe.huang@gmail.com
 * create time: 3/18/22 3:15 PM
 */
@Service
public class VerifyTokenServiceImpl implements VerifyTokenService {

    private static final Logger LOGGER = LoggerFactory.getLogger(VerifyTokenServiceImpl.class);

    @Autowired
    private VerifyTokenFeign verifyTokenFeign;

    @Autowired
    private UserCenterFeign userCenterFeign;

    @Autowired
    private UserBasicInfoMapper userBasicInfoMapper;

    @Autowired
    private RelationMapper relationMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private UidGenerator uidGenerator;

    @Autowired
    private TimService timService;

    private Random random = new Random();



    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean verifyToken(String uid, String token) {
        VerifyTokenRequest request = new VerifyTokenRequest();
        request.setToken(token);
        request.setApiId(2);
        RemoteResult<VerifyTokenResponse> remoteResult = this.verifyTokenFeign.verifyToken(request);
        LOGGER.info("校验Token结果:{} {}", request, remoteResult);
        if (!Objects.equals(remoteResult.getCode(), 0)) {
            throw new BusinessException(remoteResult.getMsg(), ResultUtils.FAIL_ON_BUSINESS.result());
        }
        VerifyTokenResponse response = remoteResult.getData();
        String userId = response.getUid();
        if (!Objects.equals(uid, userId)) {
            throw new BusinessException("token与uid不一致", ResultUtils.FAIL_ON_BUSINESS.result());
        }
        UserBasicInfo userBasicInfo = this.userBasicInfoMapper.selectByUid(userId);
        if (Objects.isNull(userBasicInfo)) {
            GetPlayerInfoRequest getPlayerInfoRequest = new GetPlayerInfoRequest();
            getPlayerInfoRequest.setApiId(2);
            getPlayerInfoRequest.setToken(token);
            RemoteResult<GetPlayerInfoResponse> getPlayerInfoResponseRemote = this.userCenterFeign.getPlayerInfo(getPlayerInfoRequest);
            LOGGER.info("获取用户信息结果: {}", getPlayerInfoResponseRemote);
            if (!Objects.equals(getPlayerInfoResponseRemote.getCode(), 0)) {
                throw new BusinessException(getPlayerInfoResponseRemote.getMsg(), ResultUtils.FAIL_ON_ERROR.result());
            }
            GetPlayerInfoResponse getPlayerInfoResponse = getPlayerInfoResponseRemote.getData();
            userBasicInfo = new UserBasicInfo();
            userBasicInfo.setId(this.uidGenerator.getUID());
            userBasicInfo.setUid(getPlayerInfoResponse.getUid());
            userBasicInfo.setNickname(getPlayerInfoResponse.getName());
            userBasicInfo.setPhoto(String.format(PHOTO, random.nextInt(5)));
            userBasicInfo.setGameLevel(getPlayerInfoResponse.getLv());
            this.userBasicInfoMapper.insert(userBasicInfo);

            Relation relation = new Relation();
            relation.setId(this.uidGenerator.getUID());
            relation.setFollowerId(getPlayerInfoResponse.getUid());
            relation.setFollowingId(getPlayerInfoResponse.getUid());
            relation.setIsDel(0);
            relation.setCreateTime(new Date());
            relation.setUpdateTime(new Date());
            this.relationMapper.insert(relation);

            this.timService.createUser(userBasicInfo.getUid(), userBasicInfo.getNickname(), userBasicInfo.getPhoto());
        }
        UserUtils.setUid(userBasicInfo.getUid());
        //TODO token -> redis
        String tokenKey = RedisKeyUtils.INSTANCE.key(RedisKey.VALUE_TOKEN, token);
        this.redisTemplate.opsForValue().set(tokenKey, userBasicInfo.getUid(), 24, TimeUnit.HOURS);

        String key = RedisKeyUtils.INSTANCE.key(RedisKey.VALUE_ACTIVE, userBasicInfo.getUid());
        this.redisTemplate.opsForValue().set(key, userBasicInfo.getUid(), 7, TimeUnit.DAYS);

        return Boolean.TRUE;
    }
}
